﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Threading;

namespace AddingEntriesToContextMenu
{
    public class IEContextMenu
    {
        [Flags]
        public enum Contexts
        {
            Default = 0x1,
            Images = 0x2,
            Controls = 0x4,
            Tables = 0x8,
            TextSelection = 0x10,
            Anchor = 0x20
        }

        #region Events
        public static event EventHandler MenuKeysRefrsh;

        protected static void OnMenuKeysRefrsh()
        {
            if (MenuKeysRefrsh != null)
            {
                MenuKeysRefrsh(null, EventArgs.Empty);
            }
        }
        #endregion

        #region Static Field and Properties
        private const string MENU_EXT = @"Software\Microsoft\Internet Explorer\MenuExt";
        private static string[] m_MenuKeys;

        public static string[] MenuKeys
        {
            get { return m_MenuKeys; }
            set { m_MenuKeys = value; }
        }
        #endregion

        #region Ctor
        public IEContextMenu(string name)
        {
            Name = name;
            Title = name;
        }

        static IEContextMenu()
        {
            SetMenuKeys();
        }
        #endregion

        #region Properties
        public string Name { get; private set; }
        public string Title { get; set; }
        public string Url { get; set; }
        public Contexts Context { get; set; }
        public bool Flag { get; set; }
        #endregion

        #region Methods
        public void Save()
        {
            using (RegistryKey menuKey = Registry.CurrentUser.OpenSubKey(MENU_EXT, RegistryKeyPermissionCheck.ReadWriteSubTree))
            {
                using (RegistryKey key = GetRegistryKey(menuKey))
                {
                    key.SetValue("", this.Url);
                    key.SetValue("Contexts", (int)this.Context);
                    key.SetValue("Flags", Flag ? 1 : 0);
                }
            }

            SetMenuKeys();
        }

        public void Delete()
        {
            using (RegistryKey menuKey = Registry.CurrentUser.OpenSubKey(MENU_EXT, RegistryKeyPermissionCheck.ReadWriteSubTree))
            {
                menuKey.DeleteSubKey(Name);
            }

            SetMenuKeys();
        }

        private RegistryKey GetRegistryKey(RegistryKey menuRegistryKey)
        {
            if (MenuKeys.Contains(Name))
            {
                return menuRegistryKey.OpenSubKey(Name, true);
            }
            else
            {
                return menuRegistryKey.CreateSubKey(Title);
            }
        }

        public override string ToString()
        {
            return Title;
        }
        #endregion    

        #region Static Methods
        public static IEContextMenu FromRegistry(string name)
        {
            IEContextMenu contexMenu = new IEContextMenu(name);
            
            using (RegistryKey subMenuKey = Registry.CurrentUser.OpenSubKey(string.Format("{0}\\{1}", MENU_EXT, name)))
            {
                contexMenu.Url = subMenuKey.GetValue("").ToString();
                contexMenu.Flag = Convert.ToBoolean((int)subMenuKey.GetValue("Flags", 0));
                contexMenu.Context = (Contexts)subMenuKey.GetValue("Contexts", 0x1);
            }

            return contexMenu;
        }

        public static void SetMenuKeys()
        {
            using (RegistryKey menuKey = Registry.CurrentUser.OpenSubKey(MENU_EXT))
            {
                MenuKeys = menuKey.GetSubKeyNames();
            }

            OnMenuKeysRefrsh();
        }

        #endregion
    }
}
